import 'package:redux/redux.dart';
import '../models/question_entity.dart';
import '../models/answer_entity.dart';
import '../data/default_qa_data.dart';

/// Redux问答状态
class ReduxQAState {
  final List<QuestionEntity> questionCollection;
  final List<AnswerEntity> answerCollection;

  const ReduxQAState({
    this.questionCollection = const [],
    this.answerCollection = const [],
  });

  ReduxQAState copyWith({
    List<QuestionEntity>? questionCollection,
    List<AnswerEntity>? answerCollection,
  }) {
    return ReduxQAState(
      questionCollection: questionCollection ?? this.questionCollection,
      answerCollection: answerCollection ?? this.answerCollection,
    );
  }
}

/// Redux问答动作
abstract class ReduxQAAction {}

class InitializeQADataAction extends ReduxQAAction {
  final List<QuestionEntity> questionList;
  final List<AnswerEntity> answerList;
  InitializeQADataAction({
    required this.questionList,
    required this.answerList,
  });
}

class AddNewQuestionAction extends ReduxQAAction {
  final QuestionEntity newQuestion;
  AddNewQuestionAction(this.newQuestion);
}

class LikeQuestionAction extends ReduxQAAction {
  final String questionId;
  final String userId;
  LikeQuestionAction({required this.questionId, required this.userId});
}

class UnlikeQuestionAction extends ReduxQAAction {
  final String questionId;
  final String userId;
  UnlikeQuestionAction({required this.questionId, required this.userId});
}

class AddAnswerAction extends ReduxQAAction {
  final AnswerEntity newAnswer;
  AddAnswerAction(this.newAnswer);
}

class LikeAnswerAction extends ReduxQAAction {
  final String answerId;
  final String userId;
  LikeAnswerAction({required this.answerId, required this.userId});
}

class UnlikeAnswerAction extends ReduxQAAction {
  final String answerId;
  final String userId;
  UnlikeAnswerAction({required this.answerId, required this.userId});
}

class DeleteQuestionAction extends ReduxQAAction {
  final String questionId;
  DeleteQuestionAction(this.questionId);
}

class DeleteAnswerAction extends ReduxQAAction {
  final String answerId;
  DeleteAnswerAction(this.answerId);
}

/// Redux问答Reducer
ReduxQAState qaReducer(ReduxQAState state, dynamic action) {
  if (action is InitializeQADataAction) {
    return state.copyWith(
      questionCollection: action.questionList,
      answerCollection: action.answerList,
    );
  }

  if (action is AddNewQuestionAction) {
    final updatedQuestions = List<QuestionEntity>.from(state.questionCollection)
      ..insert(0, action.newQuestion); // 新问题插入到顶部
    return state.copyWith(questionCollection: updatedQuestions);
  }

  if (action is LikeQuestionAction) {
    final updatedQuestions =
        state.questionCollection.map((question) {
          if (question.questionId == action.questionId) {
            if (!question.likedUserIds.contains(action.userId)) {
              final updatedLikedUsers = List<String>.from(question.likedUserIds)
                ..add(action.userId);
              return question.copyWith(
                likeCount: question.likeCount + 1,
                likedUserIds: updatedLikedUsers,
              );
            }
          }
          return question;
        }).toList();
    return state.copyWith(questionCollection: updatedQuestions);
  }

  if (action is UnlikeQuestionAction) {
    final updatedQuestions =
        state.questionCollection.map((question) {
          if (question.questionId == action.questionId) {
            if (question.likedUserIds.contains(action.userId)) {
              final updatedLikedUsers = List<String>.from(question.likedUserIds)
                ..remove(action.userId);
              return question.copyWith(
                likeCount: question.likeCount - 1,
                likedUserIds: updatedLikedUsers,
              );
            }
          }
          return question;
        }).toList();
    return state.copyWith(questionCollection: updatedQuestions);
  }

  if (action is AddAnswerAction) {
    final updatedAnswers = List<AnswerEntity>.from(state.answerCollection)
      ..add(action.newAnswer);

    // 更新对应问题的回答数
    final updatedQuestions =
        state.questionCollection.map((question) {
          if (question.questionId == action.newAnswer.questionId) {
            return question.copyWith(answerCount: question.answerCount + 1);
          }
          return question;
        }).toList();

    return state.copyWith(
      questionCollection: updatedQuestions,
      answerCollection: updatedAnswers,
    );
  }

  if (action is LikeAnswerAction) {
    final updatedAnswers =
        state.answerCollection.map((answer) {
          if (answer.answerId == action.answerId) {
            if (!answer.likedUserIds.contains(action.userId)) {
              final updatedLikedUsers = List<String>.from(answer.likedUserIds)
                ..add(action.userId);
              return answer.copyWith(
                likeCount: answer.likeCount + 1,
                likedUserIds: updatedLikedUsers,
              );
            }
          }
          return answer;
        }).toList();
    return state.copyWith(answerCollection: updatedAnswers);
  }

  if (action is UnlikeAnswerAction) {
    final updatedAnswers =
        state.answerCollection.map((answer) {
          if (answer.answerId == action.answerId) {
            if (answer.likedUserIds.contains(action.userId)) {
              final updatedLikedUsers = List<String>.from(answer.likedUserIds)
                ..remove(action.userId);
              return answer.copyWith(
                likeCount: answer.likeCount - 1,
                likedUserIds: updatedLikedUsers,
              );
            }
          }
          return answer;
        }).toList();
    return state.copyWith(answerCollection: updatedAnswers);
  }

  if (action is DeleteQuestionAction) {
    final updatedQuestions =
        state.questionCollection
            .where((question) => question.questionId != action.questionId)
            .toList();
    final updatedAnswers =
        state.answerCollection
            .where((answer) => answer.questionId != action.questionId)
            .toList();
    return state.copyWith(
      questionCollection: updatedQuestions,
      answerCollection: updatedAnswers,
    );
  }

  if (action is DeleteAnswerAction) {
    final updatedAnswers =
        state.answerCollection
            .where((answer) => answer.answerId != action.answerId)
            .toList();
    return state.copyWith(answerCollection: updatedAnswers);
  }

  return state;
}

/// Redux问答服务
class ReduxQAManager {
  static final ReduxQAManager _instance = ReduxQAManager._internal();
  factory ReduxQAManager() => _instance;
  ReduxQAManager._internal();

  Store<dynamic>? _store;

  void initialize(Store<dynamic> store) {
    _store = store;
  }

  Store<dynamic> get store {
    if (_store == null) throw Exception('QA service not initialized');
    return _store!;
  }

  void initializeQAData() {
    final qaData = DefaultQADataCollection.defaultQAData;
    store.dispatch(
      InitializeQADataAction(
        questionList: qaData.questions,
        answerList: qaData.answers,
      ),
    );
  }

  List<QuestionEntity> getAllQuestions() =>
      List.from(store.state.qaState.questionCollection);

  List<AnswerEntity> getAllAnswers() =>
      List.from(store.state.qaState.answerCollection);

  List<AnswerEntity> getAnswersByQuestionId(String questionId) {
    return store.state.qaState.answerCollection
        .where((answer) => answer.questionId == questionId)
        .toList();
  }

  QuestionEntity? getQuestionById(String questionId) {
    try {
      return store.state.qaState.questionCollection.firstWhere(
        (question) => question.questionId == questionId,
      );
    } catch (e) {
      return null;
    }
  }

  AnswerEntity? getAnswerById(String answerId) {
    try {
      return store.state.qaState.answerCollection.firstWhere(
        (answer) => answer.answerId == answerId,
      );
    } catch (e) {
      return null;
    }
  }

  bool isQuestionLikedByUser(String questionId, String userId) {
    final question = getQuestionById(questionId);
    return question?.likedUserIds.contains(userId) ?? false;
  }

  bool isAnswerLikedByUser(String answerId, String userId) {
    final answer = getAnswerById(answerId);
    return answer?.likedUserIds.contains(userId) ?? false;
  }

  int getQuestionLikeCount(String questionId) {
    final question = getQuestionById(questionId);
    return question?.likeCount ?? 0;
  }

  int getAnswerLikeCount(String answerId) {
    final answer = getAnswerById(answerId);
    return answer?.likeCount ?? 0;
  }

  int getQuestionAnswerCount(String questionId) {
    final question = getQuestionById(questionId);
    return question?.answerCount ?? 0;
  }

  Future<bool> publishQuestion(QuestionEntity newQuestion) async {
    try {
      await Future.delayed(const Duration(milliseconds: 500));
      store.dispatch(AddNewQuestionAction(newQuestion));
      return true;
    } catch (e) {
      return false;
    }
  }

  Future<bool> likeQuestion(String questionId, String userId) async {
    try {
      await Future.delayed(const Duration(milliseconds: 300));
      store.dispatch(
        LikeQuestionAction(questionId: questionId, userId: userId),
      );
      return true;
    } catch (e) {
      return false;
    }
  }

  Future<bool> unlikeQuestion(String questionId, String userId) async {
    try {
      await Future.delayed(const Duration(milliseconds: 300));
      store.dispatch(
        UnlikeQuestionAction(questionId: questionId, userId: userId),
      );
      return true;
    } catch (e) {
      return false;
    }
  }

  Future<bool> addAnswer(AnswerEntity newAnswer) async {
    try {
      await Future.delayed(const Duration(milliseconds: 400));
      store.dispatch(AddAnswerAction(newAnswer));
      return true;
    } catch (e) {
      return false;
    }
  }

  Future<bool> likeAnswer(String answerId, String userId) async {
    try {
      await Future.delayed(const Duration(milliseconds: 300));
      store.dispatch(LikeAnswerAction(answerId: answerId, userId: userId));
      return true;
    } catch (e) {
      return false;
    }
  }

  Future<bool> unlikeAnswer(String answerId, String userId) async {
    try {
      await Future.delayed(const Duration(milliseconds: 300));
      store.dispatch(UnlikeAnswerAction(answerId: answerId, userId: userId));
      return true;
    } catch (e) {
      return false;
    }
  }

  Future<bool> deleteQuestion(String questionId) async {
    try {
      await Future.delayed(const Duration(milliseconds: 300));
      store.dispatch(DeleteQuestionAction(questionId));
      return true;
    } catch (e) {
      return false;
    }
  }

  Future<bool> deleteAnswer(String answerId) async {
    try {
      await Future.delayed(const Duration(milliseconds: 300));
      store.dispatch(DeleteAnswerAction(answerId));
      return true;
    } catch (e) {
      return false;
    }
  }

  int getTotalQuestionCount() => store.state.qaState.questionCollection.length;
  int getTotalAnswerCount() => store.state.qaState.answerCollection.length;

  List<QuestionEntity> getQuestionsSortedByTime() {
    final questions = List<QuestionEntity>.from(
      store.state.qaState.questionCollection,
    );
    questions.sort((a, b) => b.publishTime.compareTo(a.publishTime));
    return questions;
  }

  List<AnswerEntity> getAnswersSortedByTime(String questionId) {
    final answers = getAnswersByQuestionId(questionId);
    answers.sort((a, b) => b.answerTime.compareTo(a.answerTime));
    return answers;
  }
}
